home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 020a / intgif11.zip / GIFUNIT.PAS next >
Pascal/Delphi Source File  |  1990-07-18  |  15KB  |  691 lines

  1. {-------------------------------------------------------------------------}
  2. {                                                                         }
  3. { GIFUnit v.1.0  -  Copyright (c) EUROPA Software, 1990   -  September 11 }
  4. {                                                                         }
  5. {-------------------------------------------------------------------------}
  6.  
  7. unit GIFUnit;
  8.  
  9.    interface
  10.  
  11.    uses dos;
  12.  
  13.    const ValSig          :  array[1..3] of char = ('G','I','F');
  14.          Version87a      :  array[1..3] of char = ('8','7','a');
  15.          Version89a      :  array[1..3] of char = ('8','9','a');
  16.          NoYo            :  array[0..1] of string[3] = (' No', 'Yes');
  17.          Extensive       =  3;
  18.          Medium          =  2;
  19.          Short           =  1;
  20.          BufferSize      =  32768;
  21.          Sizes           :  array[1..3] of word = (1024, 32768, 32768);
  22.          crlf            =  #13 + #10;
  23.          tempfilename    =  'qztp0ejf.ozp';
  24.  
  25.  
  26.    type gifheader = record
  27.  
  28.            Sig             :  array[1..3] of char;
  29.            Ver             :  array[1..3] of char;
  30.            RWidth,
  31.            RHeight         :  word;
  32.            GFeature,
  33.            Resolution,
  34.            GlobalColorMap  :  byte;  { As a byte, we can index into the   }
  35.                                      { Yes/No array for printout.         }
  36.            Interlace,
  37.            GColorMapSize,
  38.            CodeSize,
  39.            GBitsPerPixel,
  40.            Background      :  byte;
  41.  
  42.            IWidth,
  43.            IHeight,
  44.            LeftOfs,
  45.            TopOfs          :  word;
  46.  
  47.            IFeature,
  48.            LocalColorMap,
  49.            IBitsPerPixel,
  50.            LColorMapSize   :  byte;
  51.  
  52.    end;
  53.  
  54.  
  55.    type FileNodePtr   =  ^FileNode;
  56.  
  57.         FileNode      =  RECORD
  58.  
  59.             Name      :  string;
  60.             Date      :  longint;
  61.             Size      :  longint;
  62.             Next      :  FileNodePtr;
  63.  
  64.         end;
  65.  
  66.  
  67.    type Buffer        =  array[1..BufferSize] of byte;
  68.         BuffPtr       =  ^Buffer;
  69.  
  70.  
  71.    var  GifFile,
  72.         GIFOut         :  File;
  73.         GH             :  GifHeader;
  74.         Buf,
  75.         OutBuf         :  BuffPtr;
  76.         SaveExitProc   :  pointer;
  77.         recurse        :  boolean;
  78.  
  79.         TermByte,
  80.         BlockSize,
  81.         ControlCode,
  82.         Detail, Extra         :  byte;
  83.  
  84.         ImageBytes,
  85.         TotalLZW,
  86.         FileEnd,
  87.         TotalBufIdx,
  88.         TotalFiles,
  89.         NotGifs        :  longint;
  90.  
  91.         ImageNumber,
  92.         BufIdx,
  93.         OutBufIdx,
  94.         BufEnd,
  95.         BSize,
  96.         Res          :  word;
  97.  
  98.         FileHead,p,
  99.         DirHead,q      :  FileNodePtr;
  100.  
  101.         Path,StartDir,
  102.         CurrentDir,
  103.         mask,
  104.         D,N,E          :  string[80];
  105.  
  106.  
  107.         ExtensionBlock,
  108.         CommentBlock,
  109.         ImageSeperator,
  110.         GIFTerminator     :  byte;
  111.  
  112.  
  113.  
  114.    function  Getbyte        :  byte;
  115.    function  Getword        :  word;
  116.    function  AtEOF     :  boolean;
  117.    function  GetNames  :  word;
  118.    function  IsAGIF    :  boolean;
  119.    function  pad( s  :  string;  x  :  byte )  :  string;
  120.    function  rightstr( x  :  longint; w  :  byte )  :  string;
  121.    function  Leading(st : string) : String;
  122.    function  gooddate  :  string;
  123.  
  124.    procedure PutByte(  B  :  byte );
  125.    procedure PutWord(  W  :  word );
  126.    procedure FlushBuffer;
  127.    procedure FillBuffer;
  128.    procedure ReadScreenDescriptor;
  129.    procedure ReadImageDescriptor;
  130.    procedure SkipExtensionBlock;
  131.    procedure SkipAndWriteExtensionBlock;
  132.    procedure blank(x  :  byte);
  133.    procedure AddToList( Name  :  string;
  134.                         Date  :  longint;
  135.                         Size  :  longint;  var Head  :  FileNodePtr );
  136.  
  137.  
  138.    implementation
  139.  
  140.  
  141.    procedure FlushBuffer;
  142.  
  143.       begin
  144.  
  145.          blockwrite( GIFOut, OutBuf^, OutBufIdx, Res );
  146.  
  147.          OutBufIdx := 0;
  148.  
  149.       end;
  150.  
  151.  
  152.    procedure PutByte( B  :  byte );
  153.  
  154.       begin
  155.  
  156.          if OutBufIdx = BSize then FlushBuffer;
  157.  
  158.          inc(OutBufIdx);
  159.  
  160.          OutBuf^[OutBufIdx] := B;
  161.  
  162.       end;
  163.  
  164.    procedure PutWord( W  :  word );
  165.  
  166.       begin
  167.  
  168.          PutByte( lo(W) );
  169.          PutByte( hi(W) );
  170.  
  171.       end;
  172.  
  173.  
  174.  
  175.    procedure FillBuffer;
  176.  
  177.       begin
  178.  
  179.          blockread( GifFile, Buf^, BSize, BufEnd );
  180.  
  181.          BufIdx := 1;
  182.          TotalBufIdx := TotalBufIdx + BufEnd;
  183.  
  184.       end;
  185.  
  186.  
  187.    function Getbyte  :  byte;
  188.  
  189.       var LByte  :  byte;
  190.  
  191.       Begin
  192.  
  193.          if BufIdx > BSize then FillBuffer;
  194.  
  195.          Getbyte := Buf^[BufIdx];
  196.          inc(BufIdx);
  197.  
  198.       End;
  199.  
  200.  
  201.  
  202.    function Getword  : word;
  203.  
  204.       var A  :  byte;
  205.           B  :  word;  { this is a WORD so that no precision is lost when  }
  206.                        { the value is shifted into the High Byte of result }
  207.       Begin
  208.  
  209.          A := Getbyte;  { Remember LSB is first in the file stream, so B   }
  210.          B := Getbyte;  { is the high byte even though it comes last.      }
  211.  
  212.          GetWord := ((B shl 8) OR A);
  213.  
  214.       End;
  215.  
  216.    function GetAndPutbyte  :  byte;
  217.  
  218.       var h  :  byte;
  219.  
  220.       Begin
  221.  
  222.          h := GetByte;
  223.          PutByte(h);
  224.          GetAndPutByte := h;
  225.  
  226.       End;
  227.  
  228.  
  229.  
  230.    function GetAndPutWord  : Word;
  231.  
  232.       var h  :  word;
  233.  
  234.       begin
  235.  
  236.          h := GetWord;
  237.          PutWord(h);
  238.          GetAndPutWord := h;
  239.  
  240.       End;
  241.  
  242.  
  243.  
  244.    procedure ReadScreenDescriptor;
  245.  
  246.       var i  :  byte;
  247.  
  248.       begin
  249.  
  250.          for i := 1 to 3 do GH.Sig[i] := chr(getbyte);
  251.          for i := 1 to 3 do GH.Ver[i] := chr(getbyte);
  252.  
  253.          GH.RWidth         := getWord;
  254.          GH.RHeight        := getWord;
  255.          GH.GFeature       := getbyte;
  256.  
  257.          if (GH.GFeature and $80) = $80 then
  258.             GH.GlobalColorMap := 1 else GH.GlobalColorMap := 0;
  259.  
  260.          GH.Resolution     := GH.GFeature and $70 shr 5 + 1;
  261.          GH.GBitsPerPixel  := GH.GFeature and 7 + 1;
  262.          GH.Background     := GetByte;
  263.          GH.GColorMapSize  := 1 shl GH.GBitsPerPixel-1;
  264.          TermByte          := GetByte;
  265.  
  266.  
  267.          If GH.GlobalColormap = 1 then
  268.  
  269.             For I := 0 to GH.GColorMapSize do begin
  270.  
  271.                 TermByte := GetByte;
  272.                 TermByte := GetByte;
  273.                 TermByte := GetByte;
  274.  
  275.             end;
  276.  
  277.       end;
  278.  
  279.  
  280.  
  281.    procedure ReadImageDescriptor;
  282.  
  283.       var i  :  integer;
  284.  
  285.       begin
  286.  
  287.          inc(ImageNumber);
  288.  
  289.          GH.Leftofs       := GetWord;
  290.          GH.Topofs        := GetWord;
  291.          GH.IWidth        := GetWord;
  292.          GH.IHeight       := GetWord;
  293.          GH.IFeature      := GetByte;
  294.  
  295.          if (GH.IFeature and  64) =  64 then
  296.             GH.Interlace  := 1 else GH.Interlace := 0;
  297.  
  298.          if (GH.IFeature and 128) = 128 then
  299.             GH.LocalColorMap := 1 else GH.LocalColorMap := 0;
  300.  
  301.          GH.IBitsPerPixel := GH.IFeature and 7 + 1;
  302.          GH.LColorMapSize := 1 shl GH.IBitsPerPixel-1;
  303.  
  304.          if GH.LocalColormap = 1 then
  305.  
  306.             For i := 0 to GH.LColorMapSize do begin
  307.  
  308.                 TermByte := GetByte;
  309.                 TermByte := GetByte;
  310.                 TermByte := GetByte;
  311.  
  312.             end;
  313.  
  314.       end;
  315.  
  316.  
  317.    function AtEOF  :  boolean;
  318.  
  319.       begin
  320.  
  321.          AtEOF := ( FileEnd <= ((TotalBufIdx-BufEnd) + BufIdx -1) );
  322.  
  323.       end;
  324.  
  325.  
  326.    procedure ExtensionBlockResults( z  :  byte );
  327.  
  328.       begin
  329.  
  330.          writeln(crlf + 'Extension Block Function Code: ', z, ' Requested.');
  331.  
  332.       end;
  333.  
  334.  
  335.    procedure SkipExtensionBlock;
  336.  
  337.       var ExtensionFunction,i  :  byte;
  338.           ExtensionSize        :  longint;
  339.  
  340.       begin
  341.  
  342.          ExtensionFunction := GetByte;
  343.          ExtensionSize     := 0;
  344.  
  345.          repeat
  346.  
  347.              BlockSize := GetByte;
  348.  
  349.              if BufIdx+256 < BufEnd then inc(BufIdx, BlockSize)
  350.              else for i := 1 to BlockSize do TermByte := GetByte;
  351.  
  352.              inc(ExtensionSize, BlockSize);
  353.  
  354.          until ((BlockSize = 0) OR (AtEOF));
  355.  
  356.          TermByte := GetByte;
  357.  
  358.          ExtensionBlockResults(ExtensionFunction);
  359.  
  360.       end;
  361.  
  362.  
  363.  
  364.  
  365.    procedure ReadAndWriteScreenDescriptor;
  366.  
  367.       var i  :  byte;
  368.  
  369.       begin
  370.  
  371.          for i := 1 to 3 do GH.Sig[i] := chr(getAndPutbyte);
  372.          for i := 1 to 3 do GH.Ver[i] := chr(getAndPutbyte);
  373.  
  374.          GH.RWidth         := getAndPutWord;
  375.          GH.RHeight        := getAndPutWord;
  376.          GH.GFeature       := getAndPutByte;
  377.  
  378.          if (GH.GFeature and $80) = $80 then
  379.             GH.GlobalColorMap := 1 else GH.GlobalColorMap := 0;
  380.  
  381.          GH.Resolution     := GH.GFeature and $70 shr 5 + 1;
  382.          GH.GBitsPerPixel  := GH.GFeature and 7 + 1;
  383.          GH.Background     := GetAndPutByte;
  384.          GH.GColorMapSize  := 1 shl GH.GBitsPerPixel-1;
  385.          TermByte          := GetAndPutByte;
  386.  
  387.  
  388.          If GH.GlobalColormap = 1 then
  389.  
  390.             For I := 0 to GH.GColorMapSize do begin
  391.  
  392.                 TermByte := GetAndPutByte;
  393.                 TermByte := GetAndPutByte;
  394.                 TermByte := GetAndPutByte;
  395.  
  396.             end;
  397.  
  398.       end;
  399.  
  400.  
  401.  
  402.    procedure ReadAndWriteImageDescriptor;
  403.  
  404.       var i  :  integer;
  405.  
  406.       begin
  407.  
  408.          inc(ImageNumber);
  409.  
  410.          GH.Leftofs       := GetAndPutWord;
  411.          GH.Topofs        := GetAndPutWord;
  412.          GH.IWidth        := GetAndPutWord;
  413.          GH.IHeight       := GetAndPutWord;
  414.          GH.IFeature      := GetAndPutByte;
  415.  
  416.          if (GH.IFeature and  64) =  64 then
  417.             GH.Interlace  := 1 else GH.Interlace := 0;
  418.  
  419.          if (GH.IFeature and 128) = 128 then
  420.             GH.LocalColorMap := 1 else GH.LocalColorMap := 0;
  421.  
  422.          GH.IBitsPerPixel := GH.IFeature and 7 + 1;
  423.          GH.LColorMapSize := 1 shl GH.IBitsPerPixel-1;
  424.  
  425.          if GH.LocalColormap = 1 then
  426.  
  427.             For i := 0 to GH.LColorMapSize do begin
  428.  
  429.                 TermByte := GetAndPutByte;
  430.                 TermByte := GetAndPutByte;
  431.                 TermByte := GetAndPutByte;
  432.  
  433.             end;
  434.  
  435.       end;
  436.  
  437.  
  438.  
  439.    procedure SkipAndWriteExtensionBlock;
  440.  
  441.       var ExtensionFunction,i  :  byte;
  442.           ExtensionSize        :  longint;
  443.  
  444.       begin
  445.  
  446.          ExtensionFunction := GetAndPutByte;
  447.          ExtensionSize     := 0;
  448.  
  449.          repeat
  450.  
  451.              BlockSize := GetAndPutByte;
  452.  
  453.              if BufIdx+256 < BufEnd then inc(BufIdx, BlockSize)
  454.              else for i := 1 to BlockSize do TermByte := GetAndPutByte;
  455.  
  456.              inc(ExtensionSize, BlockSize);
  457.  
  458.          until ((BlockSize = 0) OR (AtEOF));
  459.  
  460.          TermByte := GetAndPutByte;
  461.  
  462.          ExtensionBlockResults(ExtensionFunction);
  463.  
  464.       end;
  465.  
  466.  
  467.  
  468.  
  469.    procedure AddToList( Name  :  string;
  470.                         Date  :  longint;
  471.                         Size  :  longint;  var Head  :  FileNodePtr );
  472.  
  473.       Var NewNode   :  FileNodePtr;
  474.           Done      :  Boolean;
  475.           ListNode  :  FileNodePtr;
  476.  
  477.       Begin
  478.  
  479.          new(NewNode);
  480.  
  481.          if NewNode = NIL then begin
  482.  
  483.             writeln('Not Enough Memory - Too many files!');
  484.             halt(1);
  485.  
  486.          end;
  487.  
  488.  
  489.          NewNode^.Name := Name;
  490.          NewNode^.Date := Date;
  491.          NewNode^.size := Size;
  492.          NewNode^.Next := NIL;
  493.  
  494.  
  495.          If Head = NIL then Head := NewNode
  496.          else
  497.  
  498.             If Name < Head^.Name then begin
  499.  
  500.                NewNode^.Next := Head;
  501.                Head          := NewNode;
  502.  
  503.             end
  504.             else begin
  505.  
  506.                Done     := FALSE;
  507.                ListNode := Head;
  508.  
  509.                While NOT Done do begin
  510.  
  511.                      If ListNode^.Next = NIL then begin
  512.  
  513.                         ListNode^.Next := NewNode;
  514.                         Done := TRUE;
  515.  
  516.                      end
  517.                      else
  518.  
  519.                         If ListNode^.Next^.Name > Name then begin
  520.  
  521.                            NewNode^.Next  := ListNode^.Next;
  522.                            ListNode^.Next := NewNode;
  523.                            Done := TRUE;
  524.  
  525.                         end
  526.                         else ListNode := ListNode^.Next;
  527.  
  528.                end;
  529.  
  530.             end;
  531.  
  532.       end;
  533.  
  534.  
  535.  
  536.  
  537.    function GetNames  :  word;
  538.  
  539.       Var F  :  SearchRec;
  540.           i  :  word;
  541.  
  542.       Begin
  543.  
  544.          FileHead := NIL;
  545.          i := 0;
  546.  
  547.          FindFirst(mask, Archive, F);
  548.  
  549.          While DosError = 0 do begin
  550.  
  551.                inc(i);
  552.                AddToList(F.name, F.Time, F.Size, FileHead);
  553.                FindNext(F);
  554.  
  555.          end;
  556.  
  557.          GetNames := i;
  558.  
  559.       end;
  560.  
  561.  
  562.  
  563.  
  564.  
  565.    function IsAGIF  :  boolean;
  566.  
  567.       const ErrMsg = ' is not a GIF file, or header is corrupt!  Skipping.';
  568.  
  569.       begin
  570.  
  571.          IsAGIF := (GH.Sig = ValSig);
  572.  
  573.       end;
  574.  
  575.  
  576.  
  577.  
  578.  
  579.    procedure blank(x  :  byte);
  580.  
  581.       var z  :  byte;
  582.  
  583.       begin
  584.  
  585.          for z := 1 to x do write(' ');
  586.  
  587.       end;
  588.  
  589.  
  590.    function pad( s  :  string;  x  :  byte )  :  string;
  591.  
  592.       var t  :  string;
  593.  
  594.       begin
  595.  
  596.          t := s;
  597.  
  598.          while length(t) < x do t := t + ' ';
  599.  
  600.          pad := t;
  601.  
  602.       end;
  603.  
  604.  
  605.    function rightstr( x  :  longint; w  :  byte )  :  string;
  606.  
  607.       var st  :  string;
  608.  
  609.       begin
  610.  
  611.          str(x, st);
  612.  
  613.          while length(st) < w do st := ' ' + st;
  614.  
  615.          rightstr := st;
  616.  
  617.       end;
  618.  
  619.  
  620.  
  621.    procedure OneHeading;
  622.  
  623.       const Head  :  array[1..2] of string =
  624.  
  625.             (( ' Filename    Horz Vert Col  Global Map  ' +
  626.                ' Color Res.  Date Stamp  File Size' + crlf +
  627.                ' --------    ---- ---- ---  ----------  ' +
  628.                ' ----------  ----------  ---------'               ),
  629.  
  630.              ( ' Filename    Horz Vert Col  Global Map  ' +
  631.                ' Color Res.    Images   Lace  LZW Bytes' + crlf +
  632.                ' --------    ---- ---- ---  ----------  ' +
  633.                ' ----------    ------   ----  ---------'          ));
  634.  
  635.       begin
  636.  
  637.          case Detail of
  638.  
  639.               1,3 : write( crlf + Head[1] + crlf );
  640.               2   : write( crlf + Head[2] + crlf );
  641.  
  642.          end;
  643.  
  644.       end;
  645.  
  646.  
  647.    function Leading(st : string) : String;
  648.  
  649.       var s  :  string;
  650.  
  651.       begin
  652.  
  653.          s := st;
  654.  
  655.          if Length(s) = 1 then s := '0' + s;
  656.          Leading := s;
  657.  
  658.       end;
  659.  
  660.  
  661.    function gooddate  :  string;
  662.  
  663.       var dt     :  datetime;
  664.           Y,M,D  :  string;
  665.  
  666.       begin
  667.  
  668.          UnPackTime(p^.date, dt );
  669.  
  670.          str(dt.Year,  Y);
  671.          str(dt.Month, M);
  672.          str(dt.Day,   D);
  673.  
  674.          GoodDate := Leading(M) + '/' + Leading(D) + '/' + copy(Y,3,2);;
  675.  
  676.       end;
  677.  
  678.  
  679.  
  680.    begin
  681.  
  682.       OutBufIdx := 0;
  683.       BSize := Sizes[3];
  684.  
  685.       ExtensionBlock  :=  33;
  686.       CommentBlock    :=  254;
  687.       ImageSeperator  :=  44;
  688.       GIFTerminator   :=  59;
  689.  
  690.    end.
  691.